from abc import ABC, abstractmethod
from typing import Dict, Any, List, Union, Optional
from src.repository.base_repository import BaseRepository
from src.common.exceptions.business_exception import BusinessException, ValidationException
from loguru import logger

class BaseService(ABC):
    """基础服务类
    
    提供通用的业务逻辑处理，包括：
    - 数据验证
    - 业务规则检查
    - 事务管理
    - 异常处理
    - 钩子方法支持
    """
    
    def __init__(self, repository: BaseRepository):
        self.repository = repository
    
    async def get_by_id(self, id: Union[int, str], include_deleted: bool = False) -> Optional[Dict[str, Any]]:
        """根据ID获取单条记录
        
        Args:
            id: 记录ID（支持雪花算法生成的大整数）
            include_deleted: 是否包含已删除的记录
            
        Returns:
            记录字典，如果不存在返回None
        """
        if not isinstance(id, (int, str)) or (isinstance(id, int) and id <= 0):
            raise ValidationException("无效的ID参数")
        
        return await self.repository.get_by_id(id, include_deleted)
    
    async def get_by_ids(self, ids: List[Union[int, str]], include_deleted: bool = False) -> List[Dict[str, Any]]:
        """根据ID列表获取多条记录"""
        if not ids:
            return []
        
        # 验证ID列表
        invalid_ids = [id for id in ids if not isinstance(id, (int, str)) or (isinstance(id, int) and id <= 0)]
        if invalid_ids:
            raise ValidationException(f"无效的ID参数: {invalid_ids}")
        
        return await self.repository.get_by_ids(ids, include_deleted)
    
    async def create(self, data: Dict[str, Any], user_id: str = None) -> Dict[str, Any]:
        """创建记录
        
        Args:
            data: 要创建的数据字典
            user_id: 操作用户ID
            
        Returns:
            创建的记录字典
        """
        # 基础验证
        await self._validate_create_data(data)
        
        # 添加审计信息
        if user_id:
            data['create_user'] = user_id
        
        # 业务逻辑验证
        await self._before_create(data)
        
        try:
            result = await self.repository.create(data)
            
            # 创建后处理
            await self._after_create(result)
            
            return result
            
        except Exception as e:
            logger.error(f"创建记录失败: {str(e)}")
            raise BusinessException(f"创建失败: {str(e)}")
    
    async def batch_create(self, data_list: List[Dict[str, Any]], user_id: str = None) -> List[Dict[str, Any]]:
        """批量创建记录
        
        Args:
            data_list: 要创建的数据字典列表
            user_id: 操作用户ID
            
        Returns:
            创建的记录字典列表
        """
        if not data_list:
            return []
        
        # 批量验证
        for data in data_list:
            await self._validate_create_data(data)
            if user_id:
                data['create_user'] = user_id
        
        # 业务逻辑验证
        await self._before_batch_create(data_list)
        
        try:
            result = await self.repository.batch_create(data_list)
            
            # 批量创建后处理
            await self._after_batch_create(result)
            
            return result
            
        except Exception as e:
            logger.error(f"批量创建记录失败: {str(e)}")
            raise BusinessException(f"批量创建失败: {str(e)}")
    
    async def update(self, id: Union[int, str], data: Dict[str, Any], user_id: str = None) -> bool:
        """更新记录
        
        Args:
            id: 记录ID（支持雪花算法生成的大整数）
            data: 要更新的数据字典
            user_id: 操作用户ID
            
        Returns:
            是否更新成功
        """
        if not isinstance(id, (int, str)) or (isinstance(id, int) and id <= 0):
            raise ValidationException("无效的ID参数")
        
        # 检查记录是否存在
        existing = await self.repository.get_by_id(id)
        if not existing:
            raise BusinessException("记录不存在")
        
        # 基础验证
        await self._validate_update_data(data, existing)
        
        # 添加审计信息
        if user_id:
            data['update_user'] = user_id
        
        # 业务逻辑验证
        await self._before_update(id, data, existing)
        
        try:
            success = await self.repository.update(id, data)
            
            if success:
                # 更新后处理
                updated_record = await self.repository.get_by_id(id)
                await self._after_update(id, updated_record, existing)
            
            return success
            
        except Exception as e:
            logger.error(f"更新记录失败: ID={id}, 错误={str(e)}")
            raise BusinessException(f"更新失败: {str(e)}")
    
    async def delete(self, id: Union[int, str], hard_delete: bool = False, user_id: str = None) -> bool:
        """删除记录
        
        Args:
            id: 记录ID（支持雪花算法生成的大整数）
            hard_delete: 是否硬删除
            user_id: 操作用户ID
            
        Returns:
            是否删除成功
        """
        if not isinstance(id, (int, str)) or (isinstance(id, int) and id <= 0):
            raise ValidationException("无效的ID参数")
        
        # 检查记录是否存在
        existing = await self.repository.get_by_id(id)
        if not existing:
            raise BusinessException("记录不存在")
        
        # 业务逻辑验证
        await self._before_delete(id, existing, hard_delete)
        
        try:
            success = await self.repository.delete(id, hard_delete, user_id)
            
            if success:
                # 删除后处理
                await self._after_delete(id, existing, hard_delete)
            
            return success
            
        except Exception as e:
            logger.error(f"删除记录失败: ID={id}, 错误={str(e)}")
            raise BusinessException(f"删除失败: {str(e)}")
    
    async def batch_delete(self, ids: List[Union[int, str]], hard_delete: bool = False, user_id: str = None) -> int:
        """批量删除记录
        
        Returns:
            删除的记录数量
        """
        if not ids:
            return 0
        
        # 验证ID列表
        invalid_ids = [id for id in ids if not isinstance(id, (int, str)) or (isinstance(id, int) and id <= 0)]
        if invalid_ids:
            raise ValidationException(f"无效的ID参数: {invalid_ids}")
        
        # 获取要删除的记录
        existing_records = await self.repository.get_by_ids(ids)
        existing_ids = [record['id'] for record in existing_records]
        
        # 业务逻辑验证
        await self._before_batch_delete(existing_ids, existing_records, hard_delete)
        
        try:
            deleted_count = await self.repository.batch_delete(existing_ids, hard_delete, user_id)
            
            if deleted_count > 0:
                # 批量删除后处理
                await self._after_batch_delete(existing_ids, existing_records, hard_delete)
            
            return deleted_count
            
        except Exception as e:
            logger.error(f"批量删除记录失败: {str(e)}")
            raise BusinessException(f"批量删除失败: {str(e)}")
    
    async def count(self, filters: Dict[str, Any] = None, include_deleted: bool = False) -> int:
        """统计记录数量"""
        return await self.repository.count(filters, include_deleted)
    
    async def exists(self, filters: Dict[str, Any], include_deleted: bool = False) -> bool:
        """检查记录是否存在"""
        return await self.repository.exists(filters, include_deleted)
    
    async def list_all(self, filters: Dict[str, Any] = None, 
                      order_by: str = None, include_deleted: bool = False) -> List[Dict[str, Any]]:
        """获取所有记录"""
        return await self.repository.list_all(filters, order_by, include_deleted)
    
    async def paginate(self, page: int = 1, size: int = 20, 
                      filters: Dict[str, Any] = None, order_by: str = None,
                      include_deleted: bool = False) -> Dict[str, Any]:
        """分页查询"""
        # 参数验证
        if page < 1:
            raise ValidationException("页码必须大于0")
        if size < 1 or size > 100:
            raise ValidationException("每页大小必须在1-100之间")
        
        return await self.repository.paginate(page, size, filters, order_by, include_deleted)
    
    # 钩子方法，子类可以重写以实现特定的业务逻辑
    
    async def _validate_create_data(self, data: Dict[str, Any]):
        """验证创建数据"""
        if not data:
            raise ValidationException("创建数据不能为空")
    
    async def _validate_update_data(self, data: Dict[str, Any], existing: Dict[str, Any]):
        """验证更新数据"""
        if not data:
            raise ValidationException("更新数据不能为空")
    
    async def _before_create(self, data: Dict[str, Any]):
        """创建前处理"""
        pass
    
    async def _after_create(self, result: Dict[str, Any]):
        """创建后处理"""
        pass
    
    async def _before_batch_create(self, data_list: List[Dict[str, Any]]):
        """批量创建前处理"""
        pass
    
    async def _after_batch_create(self, result: List[Dict[str, Any]]):
        """批量创建后处理"""
        pass
    
    async def _before_update(self, id: Union[int, str], data: Dict[str, Any], existing: Dict[str, Any]):
        """更新前处理"""
        pass
    
    async def _after_update(self, id: Union[int, str], updated: Dict[str, Any], original: Dict[str, Any]):
        """更新后处理"""
        pass
    
    async def _before_delete(self, id: Union[int, str], existing: Dict[str, Any], hard_delete: bool):
        """删除前处理"""
        pass
    
    async def _after_delete(self, id: Union[int, str], deleted: Dict[str, Any], hard_delete: bool):
        """删除后处理"""
        pass
    
    async def _before_batch_delete(self, ids: List[Union[int, str]], existing_records: List[Dict[str, Any]], hard_delete: bool):
        """批量删除前处理"""
        pass
    
    async def _after_batch_delete(self, ids: List[Union[int, str]], deleted_records: List[Dict[str, Any]], hard_delete: bool):
        """批量删除后处理"""
        pass